
#include "tasks.h"

#include <Core/logger/logger.h>
#include <core/task.h>
#include <QUuid>
#include <QMap>

namespace Optra {

class TasksControllerPrivate
{
    public:
    TasksControllerPrivate()
    {}
        ~TasksControllerPrivate() {}
        QMap<Opl::Core::Entity::EntityId, TaskEntry*> tasks;
};

TasksController::TasksController(Opl::Core::EntityObject *parent) :
    Opl::Core::EntityObject(parent), O_PRIVATE_CREATE(TasksController)
{
}

TasksController::~TasksController()
{
    O_PRIVATE_DELETE;
}
bool TasksController::start(Opl::Core::Task* task, bool autodelete, QString name/* = QString()*/)
{
    O_D(TasksController);
    Q_ASSERT(task);

    if (name.isEmpty())
        name = QString::number(task->unique());
    TaskEntry* te = new TaskEntry(name, task, autodelete);
    d->tasks.insert(task->unique(), te);
    connect(task, SIGNAL(done()), this, SLOT(taskDone()));
    LI.Debug() << "Starting Task: " << task->toString();
    task->start();
    emit tasksChanged();
    emit taskStarted(task->unique());
    return true;
}

bool TasksController::start(Opl::Core::Task* task, QString name/* = QString()*/)
{
    return start(task, true, name);
}

void TasksController::taskDone()
{
    Opl::Core::Task* t = (Opl::Core::Task*)sender();

    LI.Debug() << "Task done :" << t->unique();

    O_D(TasksController);
    Opl::Core::Entity::EntityId unique = t->unique();
    TaskEntry* te = d->tasks.value(unique);
    d->tasks.remove(unique);
    emit taskFinished(unique);
    if (te->autodelete())
    {
        LI.Trace() << "Queued to delete";
        t->deleteLater();
        te->deleteLater();
    }
}

void TasksController::stop(const Opl::Core::Entity::EntityId& uuid)
{
    O_D(TasksController);
    if (!d->tasks.contains(uuid))
    {
        LI.Warning() << "Task not found:" << uuid;
        return;
    }
    TaskEntry* entry = d->tasks[uuid];
    LI.Debug() << "Stoping task:" << uuid;
    LI.Trace() << entry->task()->toString();
    entry->task()->stop();
    //QTimer::singleShot(0, entry->task(), SLOT(stop()));
}

void TasksController::stopAll()
{
    O_D(TasksController);
    for (Opl::Core::Entity::EntityId k : d->tasks.keys())
    {
        stop(k);
    }
}
}
